#include<iostream>
#include<pthread.h>
#include<functional>
#include <unistd.h>
#include <string>
#include <cstdio>
#include <cstring>
#include <thread>

// void *routine(void *args)
// {
//     std::string name = static_cast<const char *>(args); //显示类型转换
//     while(true)
//     {
//         std::cout << "我是新线程, 我的名字是: " << name << std::endl;
//         sleep(1);
//     }
//     return 0;

// }

// //2. C++中创建线程
// int main()
// {
//     std::thread t([](){
//         while(true)
//         {
//             std::cout << "我是新线程, 我的名字是 : new thread " << std::endl;
//             sleep(1);
//         }
//     });

//     while(true)
//     {
//         std::cout << "我是main线程..." << std::endl;
//         sleep(1);
//     }
//     return 0;
// }

//1.C创建线程
// int main()
// {
//     //创建线程
//     pthread_t tid;
//     int n = pthread_create(&tid, nullptr, routine, (void *)"thread-1");
//     if(n != 0)
//     {
//         std::cout << "create thread error: " << strerror(n) << std::endl;
//         return 1;
//     }
//     while(true)
//     {
//         std::cout << "我是main线程..." << std::endl;
//         sleep(1);
//     }
//     return 0;
// }

//3. 创建多线程
// #define NUM 10

// //线程数据
// class ThreadData
// {
// public:
//     ThreadData(){}
//     void Init(const std::string &name, int a, int b)
//     {
//         _name = name;
//         _a = a;
//         _b = b;
//     }
//     void Excute()
//     {
//         _result = _a + _b;
//     }
//     int Result() {return _result;}
//     std::string Name() { return _name; }
//     void SetId(pthread_t tid) {_tid = tid; }
//     pthread_t Id() { return _tid; }
//     int A() {return _a; }
//     int B() {return _b; }
//     ~ThreadData()
//     {}
// private: 
//     std::string _name;
//     int _a;
//     int _b;
//     int _result;
//     pthread_t _tid;
// };
// //全局变量在线程内部是共享的
// int gval = 100;

// //16进制打印pid
// std::string ToHex(pthread_t tid)
// {
//     //进程内的函数, 线程共享
//     char buffer[64];
//     snprintf(buffer, sizeof(buffer), "0x%lx", tid);
//     return buffer;
// }

// void* routine(void *args)
// {
//     ThreadData *td = static_cast<ThreadData *>(args);//C++显示类型转换
//     while(true)
//     {
//         std::cout << "我是新线程, 我的名字是: " << td->Name() << ", my tid is: " << ToHex(pthread_self())
//         << ", 全局变量(会修改): " << gval << std::endl;
//         gval++;
//         td->Excute();
//         sleep(1);
//         break;
//     }
//     // int *p = new int(10);
//     // return (void*)p;
//     return td;
// }

// int main()
// {
//     ThreadData td[NUM];
//     //准备我们要加工处理的数据
//     for(int i = 0; i < NUM; i++)
//     {
//         char name[64];
//         snprintf(name, sizeof(name), "thread-%d", i);
//         td[i].Init(name, i*10, i*20);
//     }

//     //创建多线程
//     for(int i = 0; i < NUM; i++)
//     {
//         pthread_t id;
//         pthread_create(&id, nullptr, routine, &td[i]);
//         td[i].SetId(id);
//     }

//     //等待多个线程
//     for(int i = 0; i < NUM; i++)
//     {
//         pthread_join(td[i].Id(), nullptr);
//     }

//     //汇总处理结果
//     for(int i = 0; i < NUM; i++)
//     {
//         printf("td[%d]: %d+%d=%d[%ld]\n", i, td[i].A(), td[i].B(), td[i].Result(), td[i].Id());
//     }

//     return 0;
// }

//int *addr = nullptr;

// void *start(void *args)
// {
//     //pid_t id = fork();//线程中是可以创建进程的
//     //pthread_detach(pthread_self()); //线程自己可以进行分离
//     std::string name = static_cast<const char *>(args);
//     while(true) 
//     {
//         // if(addr != nullptr)
//         //     std::cout << name << "mod val a: " << (*addr)++ << std::endl;
//         std::cout << "I am a new thread" << std::endl;
//         sleep(1);
//         break;
//     }
//     //return 0; //线程退出
//     //exit(1); 任何地方调用exit, 表示进程退出
//     pthread_exit((void*)10); //进程退出
// }

// int main()
// {
//     //pthread_t tid1, tid2;
//     pthread_t tid;
//     //创建线程
//     pthread_create(&tid, nullptr, start, (void*)"thread-1");
//     //pthread_detach(tid); // 在主线程进行线程分离
//     //int n = pthread_cancel(tid); //线程取消
//     void* ret = nullptr;
//     int n = pthread_join(tid, &ret);
//     std::cout << "new thread exit code: " <<(long long int)ret << ", n: " << n << std::endl;

//     sleep(5);
//     return 0;
// }

//线程的局部存储
//__thread只能修饰内置类型
__thread int shared_value = 100;

std::string toHex(pthread_t tid)
{
    // 4. 进程内的函数，线程共享
    char buffer[64];
    snprintf(buffer, sizeof(buffer), "0x%lx", tid);
    return buffer;
}

void *start(void *args)
{
    std::string name = static_cast<const char* >(args);
    sleep(1);
    while(true)
    {
        printf("I am a new thread, name: %s, shared_value: %d, &shared_value: %p\n", 
        name.c_str(), shared_value,&shared_value);
        sleep(1);
    }
    return nullptr;
}

int main()
{
    pthread_t tid;
    pthread_create(&tid, nullptr, start, (void*)"thread-1");
    std::cout << "I am a new thread: main, " << toHex(pthread_self())
    << ", New thread id: " << toHex(tid) << std::endl;
    while(true)
    {
        printf("main thread, shared_value: %d, &shared_value: %p\n",shared_value, &shared_value);
        shared_value += 10;
        sleep(1);
    }
    pthread_join(tid, nullptr);
    return 0;
}